﻿using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using MugenInjection.Infrastructure;
using MugenInjection.Xml.Interface;

namespace MugenInjection.Xml.Infrastructure
{
    /// <summary>
    /// Represents the class for access to xml element use XElement.
    /// </summary>
    public class XElementAdapter : IXmlElement
    {
        #region Fields

        private readonly XElement _xElement;

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="XElementAdapter"/> class.
        /// </summary>
        public XElementAdapter(XElement xElement)
        {
            Validate.ArgumentNotNull(xElement, "xElement");
            _xElement = xElement;
        }

        #endregion

        #region Implementation of IXmlElement

        /// <summary>
        /// Gets original element.
        /// </summary>
        public object Element
        {
            get { return _xElement; }
        }

        /// <summary>
        /// Gets element name.
        /// </summary>
        public string Name
        {
            get { return _xElement.Name.ToString(); }
        }

        /// <summary>
        /// Gets attribute with specified name.
        /// </summary>
        /// <param name="name">Specified name.</param>
        /// <returns>An instance of <see cref="string"/>.</returns>
        public string GetAttribute(string name)
        {
            XAttribute xAttribute = _xElement.Attribute(name);
            if (xAttribute == null)
                return null;
            return xAttribute.Value;
        }

        /// <summary>
        /// Gets xml element with specified name.
        /// </summary>
        /// <param name="name">Specified name.</param>
        /// <returns>An instance of <see cref="IXmlElement"/>.</returns>
        public IXmlElement GetNode(string name)
        {
            var xElement = _xElement.Element(XName.Get(name, XmlLoaderUtils.BindingsNamespace));
            if (xElement == null)
                return null;
            return new XElementAdapter(xElement);
        }

        /// <summary>
        /// Gets xml elements with specified name.
        /// </summary>
        /// <param name="name">Specified name.</param>
        /// <returns>A series instances of <see cref="IXmlElement"/>.</returns>
        public IEnumerable<IXmlElement> GetNodes(string name)
        {
            return _xElement.Elements(XName.Get(name, XmlLoaderUtils.BindingsNamespace)).Select(element => ((IXmlElement)new XElementAdapter(element))).ToList();
        }

        #endregion
    }
}